﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Text;
using System.Threading.Tasks;
using WMIDocumentor.WMIModel;

namespace WMIDocumentor.WMIHelper
{
    public class WMILoader
    {
        private static WMILoader _current;
        public static WMILoader Current
        {
            get
            {
                if (_current == null)
                    _current = new WMILoader();
                return _current;
            }
        }

        public static WMIComputer GetComputerInformation()
        {
            WMIComputer comp = new WMIComputer();

            comp.OSInformation = GetOSInformation();
            comp.BiosInformation = GetBiosInformation();
            comp.ComputerSystemInformation = GetComputerSystemInformation();
            comp.CDRomInformation = GetCDRomInformation();
            comp.ComputerSystemProductInformation = GetComputerSystemProductInformation();
            comp.DiskInformation = GetDiskInformation();
            comp.IP4RouteTable = GetIP4RouteTable();
            comp.NTEventLog = GetNTEventLogFile();
            comp.PhysicalMemory = GetPhysicalMemory();
            comp.Process = GetProcess();
            comp.Processor = GetProcessor();
            comp.Product = GetProduct();
            comp.Registry = GetRegistry();
            comp.Service = GetService();
            comp.Share = GetShare();
            comp.SoundDevice = GetSoundDevice();
            comp.StartupCommand = GetStartupCommand();
            comp.TimerZone = GetTimeZone();
            comp.QuickFixEngineering = GetQuickFixEngineering();
            comp.VideoController = GetVideoController();
            return comp;
        
        }

        private static WMIOs[] GetOSInformation()
        {
            List<WMIOs> lstReturn = new List<WMIOs>();
            //initialize the select query with command text    
            SelectQuery query = new SelectQuery(@"Select BootDevice, Name, CSDVersion, InstallDate, OSLanguage, Version, WindowsDirectory from Win32_OperatingSystem");
            //initialize the searcher with the query it is supposed to execute   
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
            {
                var s = searcher.Get();
                foreach (ManagementObject m in s)
                {
                    WMIOs os = new WMIOs();
                    os.BootDevice = m["BootDevice"].ToString();
                    os.Name = m["Name"].ToString();
                    os.CSDVersion =m["CSDVersion"]==null?"": m["CSDVersion"].ToString();
                    os.InstallDate = m["InstallDate"].ToString();
                    os.OSLanguage = m["OSLanguage"].ToString();
                    os.Version = m["Version"].ToString();
                    os.WindowsDirectory = m["WindowsDirectory"].ToString();
                    //Console.WriteLine("GetOSInformation" + " " + m["BootDevice"] + " " + m["Name"] + " " + m["CSDVersion"] + " " + m["InstallDate"] + " " + m["OSLanguage"] + " " + m["Version"] + " " + m["WindowsDirectory"]);
                    lstReturn.Add(os);
                }
            }
            return lstReturn.ToArray();
        }
        private static WMIBios[] GetBiosInformation()
        {
            List<WMIBios> lstReturn = new List<WMIBios>();
            //initialize the select query with command text    
            SelectQuery query = new SelectQuery(@"Select BiosCharacteristics, SMBIOSBIOSVersion, SMBIOSMajorVersion, SMBIOSMinorVersion, Version from Win32_BIOS");
            //initialize the searcher with the query it is supposed to execute   
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
            {
                var s = searcher.Get();
                foreach (ManagementObject m in s)
                {
                    WMIBios bios = new WMIBios();
                    bios.BiosCharacteristics = m["BiosCharacteristics"].ToString();
                    bios.SMBIOSBIOSVersion = m["SMBIOSBIOSVersion"].ToString();
                    bios.SMBIOSMajorVersion = m["SMBIOSMajorVersion"].ToString();
                    bios.SMBIOSMinorVersion = m["SMBIOSMinorVersion"].ToString();
                    bios.Version = m["Version"].ToString();
                    //Console.WriteLine("GetBiosInformation" + " " + m["BiosCharacteristics"] + " " + m["SMBIOSBIOSVersion"] + " " + m["SMBIOSMajorVersion"] + " " + m["SMBIOSMinorVersion"] + " " + m["Version"]);
                    lstReturn.Add(bios);
                }
            }
            return lstReturn.ToArray();
        }
        private static WMIComputerSystemInformation[] GetComputerSystemInformation()
        {
            List<WMIComputerSystemInformation> lstReturn = new List<WMIComputerSystemInformation>();
            //initialize the select query with command text    
            SelectQuery query = new SelectQuery(@"Select Domain, DomainRole, Name, TotalPhysicalMemory from Win32_ComputerSystem");
            //initialize the searcher with the query it is supposed to execute   
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
            {
                var s = searcher.Get();
                foreach (ManagementObject m in s)
                {
                    WMIComputerSystemInformation wcsi = new WMIComputerSystemInformation();
                    wcsi.Domain = m["Domain"].ToString();
                    wcsi.DomainRole = m["DomainRole"].ToString();
                    wcsi.Name = m["Name"].ToString();
                    wcsi.TotalPhysicalMemory = m["TotalPhysicalMemory"].ToString();

                    lstReturn.Add(wcsi);
                }
            }
            return lstReturn.ToArray();
        }
        private static WMICD[] GetCDRomInformation()
        {
            List<WMICD> lstReturn = new List<WMICD>();
            //initialize the select query with command text    
            SelectQuery query = new SelectQuery(@"Select Drive, Manufacturer, Name from Win32_CDROMDrive");
            //initialize the searcher with the query it is supposed to execute   
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
            {
                var s = searcher.Get();
                foreach (ManagementObject m in s)
                {
                    WMICD cd = new WMICD();
                    cd.Drive = m["Drive"].ToString();
                    cd.Manufacturer = m["Manufacturer"].ToString();
                    cd.Name = m["Name"].ToString();

                    lstReturn.Add(cd);
                }
            }
            return lstReturn.ToArray();
        }
        private static WMIComputerSystemProductInformation[] GetComputerSystemProductInformation()
        {
            List<WMIComputerSystemProductInformation> lstReturn = new List<WMIComputerSystemProductInformation>();
            //initialize the select query with command text    
            SelectQuery query = new SelectQuery(@"Select Vendor, Name, IdentifyingNumber from Win32_ComputerSystemProduct");
            //initialize the searcher with the query it is supposed to execute   
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
            {
                var s = searcher.Get();
                foreach (ManagementObject m in s)
                {
                    WMIComputerSystemProductInformation wcspi = new WMIComputerSystemProductInformation();
                    wcspi.Vendor = m["Vendor"].ToString();
                    wcspi.Name = m["Name"].ToString();
                    wcspi.IdentifyingNumber = m["IdentifyingNumber"].ToString();
                    lstReturn.Add(wcspi);
                }
            }
            return lstReturn.ToArray();
        }
        private static WMIDisk[] GetDiskInformation()
        {
            List<WMIDisk> lstReturn = new List<WMIDisk>();
            //initialize the select query with command text    
            SelectQuery query = new SelectQuery(@"SELECT Caption, DeviceID, Interfacetype, Size FROM Win32_DiskDrive");
            //initialize the searcher with the query it is supposed to execute   
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
            {
                var s = searcher.Get();
                foreach (ManagementObject m in s)
                {
                    WMIDisk disk = new WMIDisk();
                    disk.Caption = m["Caption"].ToString();
                    disk.DeviceID = m["DeviceID"].ToString();
                    disk.Interfacetype = m["Interfacetype"].ToString();
                    disk.Size = m["Size"].ToString();
                    lstReturn.Add(disk);
                }
            }
            return lstReturn.ToArray();
        }
        private static WMIIPV4[] GetIP4RouteTable()
        {
            List<WMIIPV4> lstReturn = new List<WMIIPV4>();
            //initialize the select query with command text    
            SelectQuery query = new SelectQuery(@"Select Destination, Mask, NextHop from Win32_IP4RouteTable");
            //initialize the searcher with the query it is supposed to execute   
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
            {
                var s = searcher.Get();
                foreach (ManagementObject m in s)
                {
                    WMIIPV4 ipv4 = new WMIIPV4();
                    ipv4.Destination = m["Destination"].ToString();
                    ipv4.Mask = m["Mask"].ToString();
                    ipv4.NextHop = m["NextHop"].ToString();
                    lstReturn.Add(ipv4);
                }
            }
            return lstReturn.ToArray();
        }
        private static WMIEventLog[] GetNTEventLogFile()
        {
            List<WMIEventLog> lstReturn = new List<WMIEventLog>();
            //initialize the select query with command text    
            SelectQuery query = new SelectQuery(@"Select LogFileName, MaxFileSize, Name, OverwritePolicy from Win32_NTEventLogFile");
            //initialize the searcher with the query it is supposed to execute   
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
            {
                var s = searcher.Get();
                foreach (ManagementObject m in s)
                {
                    WMIEventLog eventLog = new WMIEventLog();
                    eventLog.LogFileName = m["LogFileName"].ToString();
                    eventLog.MaxFileSize = m["MaxFileSize"].ToString();
                    eventLog.Name = m["Name"].ToString();
                    eventLog.OverwritePolicy = m["OverwritePolicy"].ToString();
                    
                    lstReturn.Add(eventLog);
                }
            }
            return lstReturn.ToArray();
        }
        public static void GetIISWebServerSettings()
        {
            SelectQuery query = new SelectQuery(@"Select Name, ServerBindings, ServerComment from IISWebServerSetting");
            ManagementScope ms = new ManagementScope("root\\MicrosoftIISv2");
            //initialize the searcher with the query it is supposed to execute   
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(ms, query))
            {
                var s = searcher.Get();
                foreach (ManagementObject m in s)
                {
                    Console.WriteLine("GetIISWebServerSettings" + " " + m["Name"] + " " + m["ServerBindings"] + " " + m["ServerComment"]);
                }
            }
        }
        public static void GetIISWebVirtualDirSetting()
        {
            SelectQuery query = new SelectQuery(@"Select Name, Path from IISWebVirtualDirSetting");
            ManagementScope ms = new ManagementScope("root\\MicrosoftIISv2");
            //initialize the searcher with the query it is supposed to execute   
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(ms, query))
            {
                var s = searcher.Get();
                foreach (ManagementObject m in s)
                {
                    Console.WriteLine("GetIISWebVirtualDirSetting" + " " + m["Name"] + " " + m["Path"]);
                }
            }
        }
        public static void GetPageFile()
        {
            SelectQuery query = new SelectQuery(@"Select Drive, InitialSize, MaximumSize from Win32_PageFile");

            //initialize the searcher with the query it is supposed to execute   
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
            {
                var s = searcher.Get();
                foreach (ManagementObject m in s)
                {
                    Console.WriteLine("GetPageFile" + " " + m["Drive"] + " " + m["InitialSize"] + " " + m["MaximumSize"]);
                }
            }

        }
        public static WMIPhysicalMemory[] GetPhysicalMemory()
        {
            List<WMIPhysicalMemory> lstReturn = new List<WMIPhysicalMemory>();
            SelectQuery query = new SelectQuery(@"Select BankLabel, Capacity, FormFactor, MemoryType from Win32_PhysicalMemory");

            //initialize the searcher with the query it is supposed to execute   
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
            {
                var s = searcher.Get();
                foreach (ManagementObject m in s)
                {
                    WMIPhysicalMemory pm = new WMIPhysicalMemory();
                    pm.BankLabel = m["BankLabel"].ToString();
                    pm.Capacity = m["Capacity"].ToString();
                    pm.FormFactor = m["FormFactor"].ToString();
                    pm.MemoryType = m["MemoryType"].ToString();

                    lstReturn.Add(pm) ;
                }
            }
            return lstReturn.ToArray();
        }
        public static WMIProcess[] GetProcess()
        {
            List<WMIProcess> lstReturn = new List<WMIProcess>();
            SelectQuery query = new SelectQuery(@"Select Caption, ExecutablePath from Win32_Process");

            //initialize the searcher with the query it is supposed to execute   
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
            {
                var s = searcher.Get();
                foreach (ManagementObject m in s)
                {
                    WMIProcess proc = new WMIProcess();
                    proc.Caption = m["Caption"].ToString();
                    proc.ExecutablePath =m["ExecutablePath"]==null?"": m["ExecutablePath"].ToString();
                    lstReturn.Add(proc);
                }
            }
            return lstReturn.ToArray();
        }
        public static WMIProcessor[] GetProcessor()
        {
            List<WMIProcessor> lstReturn = new List<WMIProcessor>();
            SelectQuery query = new SelectQuery(@"Select Description, ExtClock, L2CacheSize, Name, MaxClockSpeed, SocketDesignation from Win32_Processor");

            //initialize the searcher with the query it is supposed to execute   
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
            {
                var s = searcher.Get();
                foreach (ManagementObject m in s)
                {
                    WMIProcessor proc = new WMIProcessor();
                    proc.Description = m["Description"].ToString();
                    proc.ExtClock = m["ExtClock"].ToString();
                    proc.L2CacheSize =m["L2CacheSize"]==null?"": m["L2CacheSize"].ToString();
                    proc.Name = m["Name"].ToString();
                    proc.MaxClockSpeed = m["MaxClockSpeed"].ToString();
                    proc.SocketDesignation = m["SocketDesignation"].ToString();

                    lstReturn.Add(proc);
                }
            }
            return lstReturn.ToArray();
        }
        public static WMIProduct[] GetProduct()
        {
            List<WMIProduct> lstReturn = new List<WMIProduct>();
            SelectQuery query = new SelectQuery(@"Select Name, Vendor, Version, InstallDate from Win32_Product WHERE Name <> Null");

            //initialize the searcher with the query it is supposed to execute   
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
            {
                var s = searcher.Get();
                foreach (ManagementObject m in s)
                {
                    WMIProduct prod = new WMIProduct();
                    prod.Name = m["Name"].ToString();
                    prod.Vendor = m["Vendor"].ToString();
                    prod.Version = m["Version"].ToString();
                    prod.InstallDate = m["InstallDate"].ToString();
                    lstReturn.Add(prod);
                }
            }
            return lstReturn.ToArray();
        }
        public static WMIRegistry[] GetRegistry()
        {
            List<WMIRegistry> lstReturn = new List<WMIRegistry>();
            SelectQuery query = new SelectQuery(@"Select CurrentSize, MaximumSize from Win32_Registry");

            //initialize the searcher with the query it is supposed to execute   
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
            {
                var s = searcher.Get();
                foreach (ManagementObject m in s)
                {
                    WMIRegistry reg = new WMIRegistry();
                    reg.CurrentSize = m["CurrentSize"].ToString();
                    reg.MaximumSize = m["MaximumSize"].ToString();

                    lstReturn.Add(reg);
                }
            }
            return lstReturn.ToArray();
        }
        public static WMIService[] GetService()
        {
            List<WMIService> lstReturn = new List<WMIService>();
            SelectQuery query = new SelectQuery(@"Select Caption, Started, StartMode, StartName from Win32_Service Where ServiceType ='Share Process' Or ServiceType ='Own Process'");

            //initialize the searcher with the query it is supposed to execute   
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
            {
                var s = searcher.Get();
                foreach (ManagementObject m in s)
                {
                    WMIService serv = new WMIService();
                    serv.Caption = m["Caption"].ToString();
                    serv.Started = m["Started"].ToString();
                    serv.StartMode = m["StartMode"].ToString();
                    serv.StartName = m["StartName"].ToString();
                    lstReturn.Add(serv);
                }
            }
            return lstReturn.ToArray();
        }
        public static WMIShare[] GetShare()
        {
            List<WMIShare> lstReturn = new List<WMIShare>();
            SelectQuery query = new SelectQuery(@"Select Name, Description, Path, Type from Win32_Share");

            //initialize the searcher with the query it is supposed to execute   
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
            {
                var s = searcher.Get();
                foreach (ManagementObject m in s)
                {
                    WMIShare share = new WMIShare();
                    share.Name = m["Name"].ToString();
                    share.Description = m["Description"].ToString();
                    share.Path = m["Path"].ToString();
                    share.Type = m["Type"].ToString();
                    lstReturn.Add(share);
                }
            }
            return lstReturn.ToArray();
        }
        public static WMISoundDevice[] GetSoundDevice()
        {
            List<WMISoundDevice> lstReturn = new List<WMISoundDevice>();
            SelectQuery query = new SelectQuery(@"Select Name, Manufacturer from Win32_SoundDevice");

            //initialize the searcher with the query it is supposed to execute   
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
            {
                var s = searcher.Get();
                foreach (ManagementObject m in s)
                {
                    WMISoundDevice sound = new WMISoundDevice();
                    sound.Name = m["Name"].ToString();
                    sound.Manufacturer = m["Manufacturer"].ToString();

                    lstReturn.Add(sound);
                }
            }
            return lstReturn.ToArray();
        }
        public static WMIStartupCommand[] GetStartupCommand()
        {
            List<WMIStartupCommand> lstReturn = new List<WMIStartupCommand>();
            SelectQuery query = new SelectQuery(@"Select Command, Name, User from Win32_StartupCommand");

            //initialize the searcher with the query it is supposed to execute   
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
            {
                var s = searcher.Get();
                foreach (ManagementObject m in s)
                {
                    WMIStartupCommand sc = new WMIStartupCommand();
                    sc.Command = m["Command"].ToString();
                    sc.Name = m["Name"].ToString();
                    sc.User = m["User"].ToString();
                    lstReturn.Add(sc);
                }
            }
            return lstReturn.ToArray();
        }
        public static WMITimeZone[] GetTimeZone()
        {
            List<WMITimeZone> lstReturn = new List<WMITimeZone>();
            SelectQuery query = new SelectQuery(@"Select Description from Win32_TimeZone");

            //initialize the searcher with the query it is supposed to execute   
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
            {
                var s = searcher.Get();
                foreach (ManagementObject m in s)
                {
                    WMITimeZone wtz = new WMITimeZone();
                    wtz.Description = m["Description"].ToString();
                    lstReturn.Add(wtz);
                }
            }
            return lstReturn.ToArray();
        }
        public static WMIQuickFix[] GetQuickFixEngineering()
        {
            List<WMIQuickFix> lstReturn = new List<WMIQuickFix>();
            SelectQuery query = new SelectQuery(@"Select Description, HotFixID, InstalledOn from Win32_QuickFixEngineering Where HotfixID <> 'File 1' And HotfixID <> 'Q147222'");

            //initialize the searcher with the query it is supposed to execute   
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
            {
                var s = searcher.Get();
                foreach (ManagementObject m in s)
                {
                    WMIQuickFix wqf = new WMIQuickFix();
                    wqf.Description = m["Description"].ToString();
                    wqf.HotFixID = m["HotFixID"].ToString();
                    wqf.InstalledOn = m["InstalledOn"].ToString();
                    lstReturn.Add(wqf);
                }
            }
            return lstReturn.ToArray();
        }
        public static WMIVideoController[] GetVideoController()
        {
            List<WMIVideoController> lstReturn = new List<WMIVideoController>();
            SelectQuery query = new SelectQuery(@"Select AdapterCompatibility, AdapterRAM, Name from Win32_VideoController");

            //initialize the searcher with the query it is supposed to execute   
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
            {
                var s = searcher.Get();
                foreach (ManagementObject m in s)
                {
                    WMIVideoController video = new WMIVideoController();
                    video.AdapterCompatibility = m["AdapterCompatibility"].ToString();
                    video.AdapterRAM = m["AdapterRAM"]==null?"": m["AdapterRAM"].ToString();
                    video.Name = m["Name"].ToString();
                    lstReturn.Add(video);
                }
            }
            return lstReturn.ToArray();

        }
    }
}
